#pragma once

#include <string>

#include <drogon/HttpController.h>

using namespace drogon;

namespace params
{
    // 用户参数类
    class UserParams
    {
    public:
        // 账户
        std::string account;
        // 密码
        std::string password;

        // 将参数转换为Json对象
        [[nodiscard]] virtual Json::Value toJson() const;
    };

    // 登录参数类
    class LoginParams : public UserParams
    {
    public:
        // 将登录参数转换为Json对象
        [[nodiscard]] Json::Value toJson() const override;
    };

    // 注册参数类
    class RegisterParams : public UserParams
    {
    public:
        // 用户名
        std::string username;

        // 将注册参数转换为Json对象
        [[nodiscard]] Json::Value toJson() const override;
    };
}

namespace drogon
{
    template <typename T>
    [[maybe_unused]] inline T fromRequestHelper(const HttpRequest& req)
    {
        T p;
        const auto& json = req.jsonObject();
        p.account = json->get("account", "").asString();
        p.password = json->get("password", "").asString();
        return p;
    }

    template <>
    [[maybe_unused]] inline params::RegisterParams fromRequest(const HttpRequest& req)
    {
        auto p = fromRequestHelper<params::RegisterParams>(req);
        const auto& json = req.jsonObject();
        p.username = json->get("username", "").asString();
        return p;
    }

    template <>
    [[maybe_unused]] inline params::LoginParams fromRequest(const HttpRequest& req)
    {
        return fromRequestHelper<params::LoginParams>(req);
    }
}


namespace api
{
    /**
     * 用户控制器
     */
    class User final : public drogon::HttpController<User>
    {
    public:
        METHOD_LIST_BEGIN
            METHOD_ADD(User::login, "/login", Post, "LoginFilter");
            METHOD_ADD(User::register_, "/register", Post, "RegisterFilter");

        METHOD_LIST_END

        /**
         * 登录
         * @param req 请求对象指针
         * @return http响应对象指针
         */
        static Task<HttpResponsePtr> login([[maybe_unused]] HttpRequestPtr req, params::LoginParams params);

        /**
         * 注册
         * @param req 请求对象指针
         * @param params 注册参数
         * @return http响应对象指针
         */
        static Task<HttpResponsePtr> register_([[maybe_unused]] HttpRequestPtr req, params::RegisterParams params);
    };
}
